﻿using Furion;
using SqlSugar;
using System.Linq.Expressions;

namespace ZeroAdmin.Core
{
    /// <summary>
    /// SqlSugar帮助类
    /// </summary>
    public static class SqlSugarHelper
    {

        private static readonly Lazy<ISqlSugarClient> client = new(() =>
        {
            return App.GetService<ISqlSugarClient>();
        });

        /// <summary>
        /// SqlSugarClient
        /// </summary>
        public static readonly ISqlSugarClient db = client.Value;

        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static ISugarQueryable<T> Queryable<T>()
        {
            return client.Value.Queryable<T>();
        }

        #region 建表
        /// <summary>
        /// 批量建表
        /// </summary>
        /// <param name="tableNames"></param>
        public static void CreateTable(Type[] tableNames)
        {
            db.CodeFirst.SetStringDefaultLength(255).InitTables(tableNames);
        }
        #endregion

        #region 查询
        /// <summary>
        /// 查询带条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static ISugarQueryable<T> Where<T>(Expression<Func<T, bool>> whereExpression) { 
            return Queryable<T>().Where(whereExpression);
        }

        /// <summary>
        /// 查询带条件判断
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="isWhere"></param>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static ISugarQueryable<T> WhereIF<T>(bool isWhere,Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().WhereIF(isWhere,whereExpression);
        }

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static int Count<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().Count(whereExpression);
        }

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static Task<int> CountAsync<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().CountAsync(whereExpression);
        }

        /// <summary>
        /// 检查是否存在
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static bool Any<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().Any(whereExpression);
        }

        /// <summary>
        /// 检查是否存在
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static Task<bool> AnyAsync<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().AnyAsync(whereExpression);
        }

        /// <summary>
        /// 通过主键获取实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        public static T Single<T>(dynamic primaryKey)
        {
            return Queryable<T>().InSingle(primaryKey);
        }

        /// <summary>
        /// 获取一个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        public static Task<T> SingleAsync<T>(dynamic primaryKey)
        {
            return Queryable<T>().InSingleAsync(primaryKey);
        }

        /// <summary>
        /// 获取一个实体
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static T Single<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().Single(whereExpression);
        }



        /// <summary>
        /// 获取一个实体
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static Task<T> SingleAsync<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().SingleAsync(whereExpression);
        }

        /// <summary>
        /// 获取一个实体
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static T FirstOrDefault<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().First(whereExpression);
        }

        /// <summary>
        /// 获取一个实体
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static Task<T> FirstOrDefaultAsync<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().FirstAsync(whereExpression);
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        public static List<T> ToList<T>()
        {
            return Queryable<T>().ToList();
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static  List<T> ToList<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().Where(whereExpression).ToList();
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="orderByType"></param>
        /// <returns></returns>
        public static List<T> ToList<T>(Expression<Func<T, bool>> whereExpression, Expression<Func<T, object>> orderByExpression, OrderByType orderByType = OrderByType.Asc)
        {
            return Queryable<T>().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToList();
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        public static Task<List<T>> ToListAsync<T>()
        {
            return Queryable<T>().ToListAsync();
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static Task<List<T>> ToListAsync<T>(Expression<Func<T, bool>> whereExpression)
        {
            return Queryable<T>().Where(whereExpression).ToListAsync();
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="orderByType"></param>
        /// <returns></returns>
        public static Task<List<T>> ToListAsync<T>(Expression<Func<T, bool>> whereExpression, Expression<Func<T, object>> orderByExpression, OrderByType orderByType = OrderByType.Asc)
        {
            return Queryable<T>().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToListAsync();
        }
        #endregion

        #region 新增

        /// <summary>
        /// 新增一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static int Insert<T>(T entity) where T : class, new()
        {
            return client.Value.Insertable<T>(entity).ExecuteCommand();
        }

        /// <summary>
        /// 新增多条记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public static int Insert<T>(IEnumerable<T> entitys) where T : class, new()
        {
            return client.Value.Insertable<T>(entitys).ExecuteCommand();
        }

        /// <summary>
        /// 新增一条记录返回自增Id
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static int InsertReturnIdentity<T>(T entity) where T : class, new()
        {
            return client.Value.Insertable<T>(entity).ExecuteReturnIdentity();
        }


        /// <summary>
        /// 新增一条记录返回实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static T InsertReturnEntity<T>(T entity) where T : class, new()
        {
            return client.Value.Insertable<T>(entity).ExecuteReturnEntity();
        }

        /// <summary>
        /// 新增一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static Task<int> InsertAsync<T>(T entity) where T : class, new()
        {
            return client.Value.Insertable<T>(entity).ExecuteCommandAsync();
        }


        /// <summary>
        /// 新增多条记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public static Task<int> InsertAsync<T>(IEnumerable<T> entitys) where T : class, new()
        {
            return client.Value.Insertable<T>(entitys).ExecuteCommandAsync();
        }

        /// <summary>
        /// 新增一条记录返回自增Id
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static Task<long> InsertReturnIdentityAsync<T>(T entity) where T : class, new()
        {
            return client.Value.Insertable<T>(entity).ExecuteReturnBigIdentityAsync();
        }

        /// <summary>
        /// 新增一条记录返回实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static Task<T> InsertReturnEntityAsync<T>(T entity) where T : class, new()
        {
            return client.Value.Insertable<T>(entity).ExecuteReturnEntityAsync();
        }
        #endregion

        #region 更新

        /// <summary>
        /// 更新一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static int Update<T>(T entity) where T : class, new()
        {
            return client.Value.Updateable<T>(entity).ExecuteCommand();
        }

        /// <summary>
        /// 更新多条记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public static int Update<T>(IEnumerable<T> entitys) where T : class, new()
        {
            return client.Value.Updateable<T>(entitys).ExecuteCommand();
        }

        /// <summary>
        /// 更新一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static Task<int> UpdateAsync<T>(T entity) where T : class, new()
        {
            return client.Value.Updateable<T>(entity).ExecuteCommandAsync();
        }
        /// <summary>
        /// 更新记录
        /// </summary>
        /// <param name="predicate">更新的条件</param>
        /// <param name="content">更新的内容</param>
        /// <returns></returns>
        public static int Update<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> content) where T : class, new()
        {
            return client.Value.Updateable<T>(content).Where(predicate).ExecuteCommand();
        }

        /// <summary>
        /// 更新记录
        /// </summary>
        /// <param name="predicate">更新的条件</param>
        /// <param name="content">更新的内容</param>
        /// <returns></returns>
        public static Task<int> UpdateAsync<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> content) where T : class, new()
        {
            return client.Value.Updateable<T>(content).Where(predicate).ExecuteCommandAsync();
        }


        /// <summary>
        /// 更新多条记录
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public static Task<int> UpdateAsync<T>(IEnumerable<T> entitys) where T : class, new()
        {
            return client.Value.Updateable<T>(entitys).ExecuteCommandAsync();
        }
        #endregion

        #region 删除
        /// <summary>
        /// 删除一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static int Delete<T>(T entity) where T : class, new()
        {
            return client.Value.Deleteable<T>(entity).ExecuteCommand();
        }

        /// <summary>
        /// 删除多条记录
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public static int Delete<T>(IEnumerable<T> entitys) where T : class, new()
        {
            return client.Value.Deleteable<T>(entitys).ExecuteCommand();
        }


        /// <summary>
        /// 自定义条件删除记录
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static int Delete<T>(Expression<Func<T, bool>> whereExpression) where T : class, new()
        {
            return client.Value.Deleteable<T>().Where(whereExpression).ExecuteCommand();
        }

        /// <summary>
        /// 删除一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static Task<int> DeleteAsync<T>(T entity) where T : class, new()
        {
            return client.Value.Deleteable<T>(entity).ExecuteCommandAsync();
        }

        /// <summary>
        /// 删除多条记录
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public static Task<int> DeleteAsync<T>(IEnumerable<T> entitys) where T : class, new()
        {
            return client.Value.Deleteable<T>(entitys).ExecuteCommandAsync();
        }

        /// <summary>
        /// 自定义条件删除记录
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public static Task<int> DeleteAsync<T>(Expression<Func<T, bool>> whereExpression) where T : class, new()
        {
            return  client.Value.Deleteable<T>().Where(whereExpression).ExecuteCommandAsync();
        }
        #endregion

        #region 事务
        /// <summary>
        /// 所有db
        /// </summary>
        public static void BeginTran()
        {
            db.Ado.BeginTran();
        }
        /// <summary>
        /// 所有db
        /// </summary>
        public static void CommitTran()
        {
            db.Ado.CommitTran();
        }
        /// <summary>
        /// 所有db
        /// </summary>
        public static void RollbackTran()
        {
            db.Ado.RollbackTran();
        }
        #endregion
    }
}
